package com.taobao.diamond.manager.impl;

import com.taobao.diamond.manager.DiamondPubManager;
import com.taobao.diamond.util.DiamondUtil;
import org.apache.commons.httpclient.NameValuePair;
import org.apache.commons.lang.StringUtils;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;

import java.io.IOException;
import java.net.InetAddress;
import java.util.ArrayList;
import java.util.List;

/**
 * <p></p>
 * User: <a href="mailto:yanmingming1989@163.com">严明明</a>
 * Date: 15/7/23
 * Time: 下午3:50
 */
public class DefaultDiamondPubManager implements DiamondPubManager {


    private static final Log logger = LogFactory.getLog(DefaultDiamondPubManager.class);
    static String selfIp;
    public static final long POST_TIMEOUT = 3000L;
    private ServerHttpAgent agent;
    //换行符
    public static String LINE_WRAP = "\r\n";

    static {
        try {
            selfIp = InetAddress.getLocalHost().getHostAddress();
        } catch (Exception e) {
            e.printStackTrace();
            throw new RuntimeException(e);
        }
    }

    public DefaultDiamondPubManager() {
        this.agent = new ServerHttpAgent();
    }

    @Override
    public boolean publish(String group, String dataId, String originLineContent, String newLineContent) {
        checkNotNull(new String[]{group, dataId, newLineContent});
        String allContent = DiamondUtil.getServerDataIdContent(group, dataId);
        if (StringUtils.isNotBlank(allContent)) {
            if (StringUtils.isNotBlank(originLineContent) && allContent.contains(originLineContent)) {
                while (allContent.contains(originLineContent)) {
                    //新老配置替换
                    allContent = allContent.replace(originLineContent, newLineContent);
                }
            } else if (StringUtils.isBlank(originLineContent) && allContent.contains(newLineContent)) {
                //配置已存在
                return true;
            } else {
                //新增配置
                allContent = allContent + LINE_WRAP + newLineContent;
            }
        } else {
            allContent = newLineContent;
        }


        String url = "/admin.do?method=updateConfig";
        List<org.apache.commons.httpclient.NameValuePair> params = new ArrayList<NameValuePair>();
        params.add(new org.apache.commons.httpclient.NameValuePair("group", group));
        params.add(new org.apache.commons.httpclient.NameValuePair("dataId", dataId));
        params.add(new org.apache.commons.httpclient.NameValuePair("content", allContent));

        HttpSimpleClient.HttpResult result = null;
        try {
            result = this.agent.httpPost(url, params, "GBK", 3000L);
        } catch (IOException ioe) {
            logger.warn(new StringBuilder().append("[publish-single] error, ").append(dataId).append(", ").append(group).append(", msg: ").append(ioe.toString()).toString());
            return false;
        }

        //双重检查数据已经被更新
        if (200 == result.code && result.content.contains("成功")) {
            logger.info(new StringBuilder().append("[publish-single] ok. ").append(dataId).append(", ").append(group).toString());
            return true;
        }
        logger.warn(new StringBuilder().append("[publish-single] error, ").append(dataId).append(", ").append(group).append(", error code: ").append(result.code).append(", ").append(result.content).toString());

        return false;
    }

    @Override
    public boolean unPublish(String group, String dataId, String content) {
        checkNotNull(new String[]{group, dataId, content});
        String allContent = DiamondUtil.getServerDataIdContent(group, dataId);
        if (StringUtils.isNotBlank(allContent) && StringUtils.isNotBlank(content)) {
            if (allContent.contains(content)) {
                while (allContent.contains(content)) {
                    //移除老替换
                    allContent = allContent.replace(content, "");
                }
                while (allContent.contains(LINE_WRAP+LINE_WRAP)){
                    //移除多余的空行
                    allContent = allContent.replace(LINE_WRAP+LINE_WRAP, LINE_WRAP);
                }
            } else {
                return true;
            }
        } else {
            return true;
        }

        if (StringUtils.isBlank(allContent.replace(LINE_WRAP, ""))) {
            allContent = allContent + "#配置";
        }



        String url = "/admin.do?method=updateConfig";
        List<org.apache.commons.httpclient.NameValuePair> params = new ArrayList<NameValuePair>();
        params.add(new org.apache.commons.httpclient.NameValuePair("group", group));
        params.add(new org.apache.commons.httpclient.NameValuePair("dataId", dataId));
        params.add(new org.apache.commons.httpclient.NameValuePair("content", allContent));

        HttpSimpleClient.HttpResult result = null;
        try {
            result = this.agent.httpPost(url, params, "GBK", 3000L);
        } catch (IOException ioe) {
            logger.warn(new StringBuilder().append("[publish-single] error, ").append(dataId).append(", ").append(group).append(", msg: ").append(ioe.toString()).toString());
            return false;
        }

        //双重检查数据已经被更新
        if (200 == result.code && result.content.contains("成功")) {
            logger.info(new StringBuilder().append("[publish-single] ok. ").append(dataId).append(", ").append(group).toString());
            return true;
        }
        logger.warn(new StringBuilder().append("[publish-single] error, ").append(dataId).append(", ").append(group).append(", error code: ").append(result.code).append(", ").append(result.content).toString());

        return false;
    }

    @Override
    public boolean publishAll(String group, String dataId, String content) {
        checkNotNull(new String[]{group, dataId, content});

        String url = "/admin.do?method=updateConfig";
        List<org.apache.commons.httpclient.NameValuePair> params = new ArrayList<NameValuePair>();
        params.add(new org.apache.commons.httpclient.NameValuePair("group", group));
        params.add(new org.apache.commons.httpclient.NameValuePair("dataId", dataId));
        params.add(new org.apache.commons.httpclient.NameValuePair("content", content));

        HttpSimpleClient.HttpResult result = null;
        try {
            result = this.agent.httpPost(url, params, "GBK", 3000L);
        } catch (IOException ioe) {
            logger.warn(new StringBuilder().append("[publish-single] error, ").append(dataId).append(", ").append(group).append(", msg: ").append(ioe.toString()).toString());
            return false;
        }

        //双重检查数据已经被更新
        if (200 == result.code && result.content.contains("成功")) {
            logger.info(new StringBuilder().append("[publish-single] ok. ").append(dataId).append(", ").append(group).toString());
            return true;
        }
        logger.warn(new StringBuilder().append("[publish-single] error, ").append(dataId).append(", ").append(group).append(", error code: ").append(result.code).append(", ").append(result.content).toString());

        return false;
    }


    private void checkNotNull(String[] params) {
        for (String param : params) {
            if (StringUtils.isBlank(param))
                throw new IllegalArgumentException("param cannot be blank");
        }
    }
}
